package com.luhuiguo.cms.client.ui;

import java.util.Date;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.gen2.table.client.AbstractColumnDefinition;
import com.google.gwt.gen2.table.client.CellRenderer;
import com.google.gwt.gen2.table.client.ColumnDefinition;
import com.google.gwt.gen2.table.client.DefaultRowRenderer;
import com.google.gwt.gen2.table.client.DefaultTableDefinition;
import com.google.gwt.gen2.table.client.FixedWidthGridBulkRenderer;
import com.google.gwt.gen2.table.client.PagingOptions;
import com.google.gwt.gen2.table.client.PagingScrollTable;
import com.google.gwt.gen2.table.client.ScrollTable;
import com.google.gwt.gen2.table.client.TableDefinition;
import com.google.gwt.gen2.table.client.SelectionGrid.SelectionPolicy;
import com.google.gwt.gen2.table.client.TableDefinition.AbstractCellView;
import com.google.gwt.gen2.table.event.client.HasPageLoadHandlers;
import com.google.gwt.gen2.table.event.client.HasRowSelectionHandlers;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.AppConstants;
import com.luhuiguo.cms.client.AppMessages;
import com.luhuiguo.cms.client.presenter.ArticleTableModel;
import com.luhuiguo.cms.client.presenter.ArticlesPresenter;
import com.luhuiguo.cms.shared.model.ArticleModel;

@SuppressWarnings("deprecation")
public class ArticlesView extends Composite implements ArticlesPresenter.Display {

    private static ArticlesViewUiBinder uiBinder = GWT.create(ArticlesViewUiBinder.class);

    interface ArticlesViewUiBinder extends UiBinder<Widget, ArticlesView> {
    }

    @UiField
    Button refreshButton;

    @UiField
    Button addButton;

    @UiField
    Button deleteButton;

    @UiField(provided = true)
    PagingScrollTable<ArticleModel> articleTable;

    @UiField(provided = true)
    PagingOptions pagingOptions;

    private ArticleTableModel tableModel;

    // private CachedTableModel<ArticleModel> cachedTableModel;

    private DefaultTableDefinition<ArticleModel> tableDefinition;

    private AppConstants constants;

    private AppMessages messages;

    @Inject
    public ArticlesView(ArticleTableModel tableModel, AppConstants constants, AppMessages messages) {
        super();
        this.tableModel = tableModel;
        this.constants = constants;
        this.messages = messages;
        createScrollTable();
        pagingOptions = new PagingOptions(articleTable);

        initWidget(uiBinder.createAndBindUi(this));

        articleTable.gotoFirstPage();

    }

    protected PagingScrollTable<ArticleModel> createScrollTable() {
        // Setup the controller
        // cachedTableModel = new CachedTableModel<ArticleModel>(tableModel);
        // cachedTableModel.setRowCount(CachedTableModel.UNKNOWN_ROW_COUNT);

        // Create a TableCellRenderer
        TableDefinition<ArticleModel> tableDef = createTableDefinition();

        // Create the scroll table
        articleTable = new PagingScrollTable<ArticleModel>(tableModel, tableDef);
        articleTable.setPageSize(constants.defaultPageSize());
        articleTable.getDataTable().setSelectionPolicy(SelectionPolicy.CHECKBOX);
        articleTable.setEmptyTableWidget(new HTML(constants.noData()));

        // Setup the bulk renderer
        FixedWidthGridBulkRenderer<ArticleModel> bulkRenderer = new FixedWidthGridBulkRenderer<ArticleModel>(
                articleTable.getDataTable(), articleTable);
        articleTable.setBulkRenderer(bulkRenderer);

        // Setup the formatting
        articleTable.setCellPadding(3);
        articleTable.setCellSpacing(0);
        articleTable.setResizePolicy(ScrollTable.ResizePolicy.FILL_WIDTH);

        return articleTable;
    }

    private TableDefinition<ArticleModel> createTableDefinition() {

        tableDefinition = new DefaultTableDefinition<ArticleModel>();

        String[] rowColors = new String[]{ constants.oddRowColor(), constants.evenRowColor() };
        tableDefinition.setRowRenderer(new DefaultRowRenderer<ArticleModel>(rowColors));

        {
            AbstractColumnDefinition<ArticleModel, String> columnDef = new AbstractColumnDefinition<ArticleModel, String>() {
                @Override
                public String getCellValue(ArticleModel rowValue) {
                    return rowValue.getTitle();
                }

                @Override
                public void setCellValue(ArticleModel rowValue, String cellValue) {
                    rowValue.setTitle(cellValue);
                }
            };

            columnDef.setMinimumColumnWidth(200);
            columnDef.setPreferredColumnWidth(300);
            columnDef.setColumnSortable(false);
            columnDef.setColumnTruncatable(false);

            columnDef.setHeader(0, new HTML(constants.title()));
            columnDef.setHeaderCount(1);
            columnDef.setHeaderTruncatable(false);
            tableDefinition.addColumnDefinition(columnDef);
        }
        {
            AbstractColumnDefinition<ArticleModel, String> columnDef = new AbstractColumnDefinition<ArticleModel, String>() {
                @Override
                public String getCellValue(ArticleModel rowValue) {
                    return rowValue.getAuthor();
                }

                @Override
                public void setCellValue(ArticleModel rowValue, String cellValue) {
                    rowValue.setAuthor(cellValue);
                }
            };

            columnDef.setMinimumColumnWidth(50);
            columnDef.setPreferredColumnWidth(60);
            columnDef.setColumnSortable(false);
            columnDef.setColumnTruncatable(false);

            columnDef.setHeader(0, new HTML(constants.author()));
            columnDef.setHeaderCount(1);
            columnDef.setHeaderTruncatable(false);
            tableDefinition.addColumnDefinition(columnDef);
        }
        {
            AbstractColumnDefinition<ArticleModel, String> columnDef = new AbstractColumnDefinition<ArticleModel, String>() {
                @Override
                public String getCellValue(ArticleModel rowValue) {
                    return rowValue.getSource();
                }

                @Override
                public void setCellValue(ArticleModel rowValue, String cellValue) {
                    rowValue.setSource(cellValue);
                }
            };

            columnDef.setMinimumColumnWidth(50);
            columnDef.setPreferredColumnWidth(60);
            columnDef.setColumnSortable(false);
            columnDef.setColumnTruncatable(false);

            columnDef.setHeader(0, new HTML(constants.source()));
            columnDef.setHeaderCount(1);
            columnDef.setHeaderTruncatable(false);
            tableDefinition.addColumnDefinition(columnDef);
        }
        {
            AbstractColumnDefinition<ArticleModel, Integer> columnDef = new AbstractColumnDefinition<ArticleModel, Integer>() {
                @Override
                public Integer getCellValue(ArticleModel rowValue) {
                    return rowValue.getStatus();
                }

                @Override
                public void setCellValue(ArticleModel rowValue, Integer cellValue) {
                    rowValue.setStatus(cellValue);
                }
            };
            columnDef.setCellRenderer(new CellRenderer<ArticleModel, Integer>() {

                @Override
                public void renderRowValue(ArticleModel rowValue, ColumnDefinition<ArticleModel, Integer> columnDef,
                        AbstractCellView<ArticleModel> view) {

                    int status = rowValue.getStatus();

                    switch (status) {
                    case 0:
                        view.setHTML(constants.drift());
                        break;
                    case 1:
                        view.setHTML(constants.edit());
                        break;
                    case 2:
                        view.setHTML(constants.approved());
                        break;
                    case 3:
                        view.setHTML(constants.published());
                        break;
                    default:
                        view.setHTML(constants.abandoned());
                    }

                }

            });
            columnDef.setMinimumColumnWidth(50);
            columnDef.setPreferredColumnWidth(60);
            columnDef.setColumnSortable(false);
            columnDef.setColumnTruncatable(false);

            columnDef.setHeader(0, new HTML(constants.status()));
            columnDef.setHeaderCount(1);
            columnDef.setHeaderTruncatable(false);
            tableDefinition.addColumnDefinition(columnDef);
        }
        {
            AbstractColumnDefinition<ArticleModel, Date> columnDef = new AbstractColumnDefinition<ArticleModel, Date>() {
                @Override
                public Date getCellValue(ArticleModel rowValue) {
                    return rowValue.getLastModified();
                }

                @Override
                public void setCellValue(ArticleModel rowValue, Date cellValue) {
                    rowValue.setLastModified(cellValue);
                }
            };

            columnDef.setCellRenderer(new CellRenderer<ArticleModel, Date>() {

                @Override
                public void renderRowValue(ArticleModel rowValue, ColumnDefinition<ArticleModel, Date> columnDef,
                        AbstractCellView<ArticleModel> view) {
                    DateTimeFormat dtformat = DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss");
                    view.setHTML(dtformat.format(rowValue.getLastModified()));
                    view.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);

                }

            });

            columnDef.setMinimumColumnWidth(50);
            columnDef.setPreferredColumnWidth(80);
            columnDef.setColumnSortable(false);
            columnDef.setColumnTruncatable(false);

            columnDef.setHeader(0, new HTML(constants.lastModified()));
            columnDef.setHeaderCount(1);
            columnDef.setHeaderTruncatable(false);
            tableDefinition.addColumnDefinition(columnDef);
        }

        {
            AbstractColumnDefinition<ArticleModel, String> columnDef = new AbstractColumnDefinition<ArticleModel, String>() {
                @Override
                public String getCellValue(ArticleModel rowValue) {
                    return rowValue.getLastModifiedBy();
                }

                @Override
                public void setCellValue(ArticleModel rowValue, String cellValue) {
                    rowValue.setLastModifiedBy(cellValue);
                }
            };

            columnDef.setMinimumColumnWidth(50);
            columnDef.setPreferredColumnWidth(80);
            columnDef.setColumnSortable(false);
            columnDef.setColumnTruncatable(false);

            columnDef.setHeader(0, new HTML(constants.lastModifiedBy()));
            columnDef.setHeaderCount(1);
            columnDef.setHeaderTruncatable(false);
            tableDefinition.addColumnDefinition(columnDef);
        }
        return tableDefinition;
    }

    @Override
    public void setLoading(boolean loading) {

    }

    @Override
    public Widget asWidget() {
        return this;
    }

    @Override
    public HasClickHandlers getAddClick() {
        return addButton;
    }

    @Override
    public HasClickHandlers getDeleteClick() {
        return deleteButton;
    }

    @Override
    public HasClickHandlers getRefreshClick() {
        return refreshButton;
    }

    @Override
    public void reloadData() {
        articleTable.reloadPage();

    }

    @Override
    public void reset() {
        // pagingOptions.setSelectedIndex(0);
        // cachedTableModel.clearCache();
        // cachedTableModel.setRowCount(CachedTableModel.UNKNOWN_ROW_COUNT);
        articleTable.gotoFirstPage();

    }

    @Override
    public Set<ArticleModel> getSelectedArticles() {
        return articleTable.getSelectedRowValues();
    }

    @Override
    public HasRowSelectionHandlers getDataTableSelection() {
        return articleTable.getDataTable();
    }

    @Override
    public void setDeleteEnabled(boolean enabled) {
        deleteButton.setEnabled(enabled);

    }

    @Override
    public HasPageLoadHandlers getDataTableLoad() {
        return articleTable;
    }

    @Override
    public ArticleModel getData(int row) {

        return articleTable.getRowValue(row);
    }

    public void addTableListener(TableListener listener) {
        articleTable.getDataTable().addTableListener(listener);

    }

    public void removeTableListener(TableListener listener) {
        articleTable.getDataTable().removeTableListener(listener);
    }

}
